home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / share / gtk-2.0 / demo / rotated_text.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-25  |  4.8 KB  |  143 lines

  1. /* Rotated Text
  2.  *
  3.  * This demo shows how to use GDK and Pango to draw rotated and transformed
  4.  * text. The use of GdkPangoRenderer in this example is a somewhat advanced
  5.  * technique; most applications can simply use gdk_draw_layout(). We use
  6.  * it here mostly because that allows us to work in user coordinates - that is,
  7.  * coordinates prior to the application of the transformation matrix, rather
  8.  * than device coordinates.
  9.  *
  10.  * As of GTK+-2.6, the ability to draw transformed and anti-aliased graphics
  11.  * as shown in this example is only present for text. With GTK+-2.8, a new
  12.  * graphics system called "Cairo" will be introduced that provides these
  13.  * capabilities and many more for all types of graphics.
  14.  */
  15. #include <math.h>
  16. #include <gtk/gtk.h>
  17.  
  18. static GtkWidget *window = NULL;
  19.  
  20. static gboolean
  21. rotated_text_expose_event (GtkWidget      *widget,
  22.                GdkEventExpose *event,
  23.                gpointer       data)
  24. {
  25. #define RADIUS 150
  26. #define N_WORDS 10
  27. #define FONT "Sans Bold 27"
  28.   
  29.   PangoRenderer *renderer;
  30.   PangoMatrix matrix = PANGO_MATRIX_INIT;
  31.   PangoContext *context;
  32.   PangoLayout *layout;
  33.   PangoFontDescription *desc;
  34.  
  35.   int width = widget->allocation.width;
  36.   int height = widget->allocation.height;
  37.   double device_radius;
  38.   int i;
  39.  
  40.   /* Get the default renderer for the screen, and set it up for drawing  */
  41.   renderer = gdk_pango_renderer_get_default (gtk_widget_get_screen (widget));
  42.   gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer), widget->window);
  43.   gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer), widget->style->black_gc);
  44.  
  45.   /* Set up a transformation matrix so that the user space coordinates for
  46.    * the centered square where we draw are [-RADIUS, RADIUS], [-RADIUS, RADIUS]
  47.    * We first center, then change the scale */
  48.   device_radius = MIN (width, height) / 2.;
  49.   pango_matrix_translate (&matrix,
  50.               device_radius + (width - 2 * device_radius) / 2,
  51.               device_radius + (height - 2 * device_radius) / 2);
  52.   pango_matrix_scale (&matrix, device_radius / RADIUS, device_radius / RADIUS);
  53.  
  54.   /* Create a PangoLayout, set the font and text */
  55.   context = gtk_widget_create_pango_context (widget);
  56.   layout = pango_layout_new (context);
  57.   pango_layout_set_text (layout, "Text", -1);
  58.   desc = pango_font_description_from_string (FONT);
  59.   pango_layout_set_font_description (layout, desc);
  60.   pango_font_description_free (desc);
  61.  
  62.   /* Draw the layout N_WORDS times in a circle */
  63.   for (i = 0; i < N_WORDS; i++)
  64.     {
  65.       GdkColor color;
  66.       PangoMatrix rotated_matrix = matrix;
  67.       int width, height;
  68.       double angle = (360. * i) / N_WORDS;
  69.  
  70.       /* Gradient from red at angle == 60 to blue at angle == 300 */
  71.       color.red   = 65535 * (1 + cos ((angle - 60) * G_PI / 180.)) / 2;
  72.       color.green = 0;
  73.       color.blue  = 65535  - color.red;
  74.     
  75.       gdk_pango_renderer_set_override_color (GDK_PANGO_RENDERER (renderer),
  76.                          PANGO_RENDER_PART_FOREGROUND, &color);
  77.                                              
  78.       pango_matrix_rotate (&rotated_matrix, angle);
  79.  
  80.       pango_context_set_matrix (context, &rotated_matrix);
  81.     
  82.       /* Inform Pango to re-layout the text with the new transformation matrix */
  83.       pango_layout_context_changed (layout);
  84.     
  85.       pango_layout_get_size (layout, &width, &height);
  86.       pango_renderer_draw_layout (renderer, layout,
  87.                   - width / 2, - RADIUS * PANGO_SCALE);
  88.     }
  89.  
  90.   /* Clean up default renderer, since it is shared */
  91.   gdk_pango_renderer_set_override_color (GDK_PANGO_RENDERER (renderer),
  92.                      PANGO_RENDER_PART_FOREGROUND, NULL);
  93.   gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (renderer), NULL);
  94.   gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (renderer), NULL);
  95.  
  96.   /* free the objects we created */
  97.   g_object_unref (layout);
  98.   g_object_unref (context);
  99.   
  100.   return FALSE;
  101. }
  102.  
  103. GtkWidget *
  104. do_rotated_text (GtkWidget *do_widget)
  105. {
  106.   GtkWidget *drawing_area;
  107.   
  108.   if (!window)
  109.     {
  110.       const GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
  111.       
  112.       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  113.       gtk_window_set_screen (GTK_WINDOW (window),
  114.                  gtk_widget_get_screen (do_widget));
  115.       gtk_window_set_title (GTK_WINDOW (window), "Rotated Text");
  116.  
  117.       g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
  118.  
  119.       drawing_area = gtk_drawing_area_new ();
  120.       gtk_container_add (GTK_CONTAINER (window), drawing_area);
  121.  
  122.       /* This overrides the background color from the theme */
  123.       gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &white);
  124.  
  125.       g_signal_connect (drawing_area, "expose-event",
  126.             G_CALLBACK (rotated_text_expose_event), NULL);
  127.  
  128.       gtk_window_set_default_size (GTK_WINDOW (window), 2 * RADIUS, 2 * RADIUS);
  129.     }
  130.  
  131.   if (!GTK_WIDGET_VISIBLE (window))
  132.     {
  133.       gtk_widget_show_all (window);
  134.     }
  135.   else
  136.     {
  137.       gtk_widget_destroy (window);
  138.       window = NULL;
  139.     }
  140.  
  141.   return window;
  142. }
  143.